/*
 * Copyright (c) 2007 jNetX.
 * http://www.jnetx.com
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * jNetX. You shall not disclose such Confidential Information and
 * shall use it only in accordance with the terms of the license
 * agreement you entered into with jNetX.
 *
 * $Id$
 */
package com.jnetx.javax.sip.header;

import javax.sip.InvalidArgumentException;
import javax.sip.address.Address;
import javax.sip.address.URI;
import javax.sip.header.*;
import java.text.ParseException;
import java.util.*;

/**
 * The implementation of {@link HeaderFactory} interface.
 *
 * @author <a href="mailto:dparhonin@jnetx.ru">Dmitry Parhonin</a>
 * @version $Revision$
 */
public class HeaderFactoryImpl implements HeaderFactory {
    /**
     * Creates a new AcceptEncodingHeader based on the newly supplied encoding
     * value.
     *
     * @param encoding the new string containing the encoding value.
     * @return the newly created AcceptEncodingHeader object.
     * @throws ParseException which signals that an error has been reached
     *                        unexpectedly while parsing the encoding value.
     */
    public AcceptEncodingHeader createAcceptEncodingHeader(String encoding) throws ParseException {
        final AcceptEncodingHeader header = new AcceptEncodingHeaderImpl();
        header.setEncoding(encoding);
        return header;
    }

    /**
     * Creates a new AcceptHeader based on the newly supplied contentType and
     * contentSubType values.
     *
     * @param contentType    the new string content type value.
     * @param contentSubType the new string content sub-type value.
     * @return the newly created AcceptHeader object.
     * @throws ParseException which signals that an error has been reached
     *                        unexpectedly while parsing the content type or content subtype value.
     */
    public AcceptHeader createAcceptHeader(String contentType, String contentSubType) throws ParseException {
        final AcceptHeader header = new AcceptHeaderImpl();
        header.setContentType(contentType);
        header.setContentSubType(contentSubType);
        return header;
    }

    /**
     * Creates a new AcceptLanguageHeader based on the newly supplied
     * language value.
     *
     * @param language the new Locale value of the language
     * @return the newly created AcceptLanguageHeader object.
     */
    public AcceptLanguageHeader createAcceptLanguageHeader(Locale language) {
        final AcceptLanguageHeader header = new AcceptLanguageHeaderImpl();
        header.setAcceptLanguage(language);
        return header;
    }

    /**
     * Creates a new AlertInfoHeader based on the newly supplied alertInfo value.
     *
     * @param alertInfo the new URI value of the alertInfo.
     * @return the newly created AlertInfoHeader object.
     */
    public AlertInfoHeader createAlertInfoHeader(URI alertInfo) {
        final AlertInfoHeader header = new AlertInfoHeaderImpl();
        header.setAlertInfo(alertInfo);
        return header;
    }

    /**
     * Creates a new AllowEventsHeader based on the newly supplied event type
     * value.
     *
     * @param eventType the new string containing the eventType value.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the eventType value.
     * @return the newly created AllowEventsHeader object.
     */
    public AllowEventsHeader createAllowEventsHeader(String eventType) throws ParseException {
        final AllowEventsHeader header = new AllowEventsHeaderImpl();
        header.setEventType(eventType);
        return header;
    }

    /**
     * Creates a new AllowHeader based on the newly supplied method value.
     *
     * @param method the new string containing the method value.
     * @return the newly created AllowHeader object.
     * @throws ParseException which signals that an error has been reached
     *                        unexpectedly while parsing the method value.
     */
    public AllowHeader createAllowHeader(String method) throws ParseException {
        final AllowHeader header = new AllowHeaderImpl();
        header.setMethod(method);
        return header;
    }

    /**
     * Creates a new AuthenticationInfoHeader based on the newly supplied
     * response value.
     *
     * @param response the new string value of the response.
     * @return the newly created AuthenticationInfoHeader object.
     * @throws ParseException which signals that an error has been reached
     *                        unexpectedly while parsing the response value.
     */
    public AuthenticationInfoHeader createAuthenticationInfoHeader(String response) throws ParseException {
        final AuthenticationInfoHeader header = new AuthenticationInfoHeaderImpl();
        header.setResponse(response);
        return header;
    }

    /**
     * Creates a new AuthorizationHeader based on the newly supplied
     * scheme value.
     *
     * @param scheme the new string value of the scheme.
     * @return the newly created AuthorizationHeader object.
     * @throws ParseException which signals that an error has been reached
     *                        unexpectedly while parsing the scheme value.
     */
    public AuthorizationHeader createAuthorizationHeader(String scheme) throws ParseException {
        final AuthorizationHeader header = new AuthorizationHeaderImpl();
        header.setScheme(scheme);
        return header;
    }

    /**
     * Creates a new CSeqHeader based on the newly supplied sequence number and
     * method values.
     *
     * @param sequenceNumber the new integer value of the sequence number.
     * @param method         the new string value of the method.
     * @return the newly created CSeqHeader object.
     * @throws InvalidArgumentException if supplied sequence number is less
     *                                  than zero.
     * @throws ParseException           which signals that an error has been reached
     *                                  unexpectedly while parsing the method value.
     * @deprecated Use {@link #createCSeqHeader(long,String)} method
     *             with type long.
     */
    public CSeqHeader createCSeqHeader(int sequenceNumber, String method) throws ParseException, InvalidArgumentException {
        final CSeqHeader header = new CSeqHeaderImpl();
        header.setMethod(method);
        header.setSequenceNumber(sequenceNumber);
        return header;
    }

    /**
     * Creates a new CSeqHeader based on the newly supplied sequence number and
     * method values.
     *
     * @param sequenceNumber the new long value of the sequence number.
     * @param method         the new string value of the method.
     * @return the newly created CSeqHeader object.
     * @throws InvalidArgumentException if supplied sequence number is less
     *                                  than zero.
     * @throws ParseException           which signals that an error has been reached
     *                                  unexpectedly while parsing the method value.
     */
    public CSeqHeader createCSeqHeader(long sequenceNumber, String method) throws ParseException, InvalidArgumentException {
        final CSeqHeader header = new CSeqHeaderImpl();
        header.setMethod(method);
        header.setSeqNumber(sequenceNumber);
        return header;
    }

    /**
     * Creates a new CallIdHeader based on the newly supplied callId value.
     *
     * @param callId the new string value of the call-id.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the callId value.
     * @return the newly created CallIdHeader object.
     */
    public CallIdHeader createCallIdHeader(String callId) throws ParseException {
        final CallIdHeader header = new CallIdHeaderImpl();
        header.setCallId(callId);
        return header;
    }

    /**
     * Creates a new CallInfoHeader based on the newly supplied callInfo value.
     *
     * @param callInfo the new URI value of the callInfo.
     * @return the newly created CallInfoHeader object.
     */
    public CallInfoHeader createCallInfoHeader(URI callInfo) {
        final CallInfoHeader header = new CallInfoHeaderImpl();
        header.setInfo(callInfo);
        return header;
    }

    /**
     * Creates a new ContactHeader based on the newly supplied address value.
     *
     * @param address the new Address value of the address.
     * @return the newly created ContactHeader object.
     */
    public ContactHeader createContactHeader(Address address) {
        final ContactHeader header = new ContactHeaderImpl();
        header.setAddress(address);
        return header;
    }

    /**
     * Creates a new wildcard ContactHeader. This is used in Register requests
     * to indicate to the server that it should remove all locations the
     * at which the user is currently available. This implies that the
     * following conditions are met:
     * <ul>
     * <li><code>ContactHeader.getAddress.getUserInfo() == *;</code>
     * <li><code>ContactHeader.getAddress.isWildCard() == true;</code>
     * <li><code>ContactHeader.getExpires() == 0;</code>
     * </ul>
     *
     * @return the newly created wildcard ContactHeader.
     */
    public ContactHeader createContactHeader() {
        final ContactHeader header = new ContactHeaderImpl();
        header.setWildCard();
        return header;
    }

    /**
     * Creates a new ContentDispositionHeader based on the newly supplied
     * contentDisposition value.
     *
     * @param contentDispositionType the new string value of the contentDisposition.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the contentDisposition value.
     * @return the newly created ContentDispositionHeader object.
     */
    public ContentDispositionHeader createContentDispositionHeader(String contentDispositionType) throws ParseException {
        final ContentDispositionHeader header = new ContentDispositionHeaderImpl();
        header.setDispositionType(contentDispositionType);
        return header;
    }

    /**
     * Creates a new ContentEncodingHeader based on the newly supplied encoding
     * value.
     *
     * @param encoding the new string containing the encoding value.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the encoding value.
     * @return the newly created ContentEncodingHeader object.
     */
    public ContentEncodingHeader createContentEncodingHeader(String encoding) throws ParseException {
        final ContentEncodingHeader header = new ContentEncodingHeaderImpl();
        header.setEncoding(encoding);
        return header;
    }

    /**
     * Creates a new ContentLanguageHeader based on the newly supplied
     * contentLanguage value.
     *
     * @param contentLanguage the new Locale value of the contentLanguage.
     * @return the newly created ContentLanguageHeader object.
     */
    public ContentLanguageHeader createContentLanguageHeader(Locale contentLanguage) {
        final ContentLanguageHeader header = new ContentLanguageHeaderImpl();
        header.setContentLanguage(contentLanguage);
        return header;
    }

    /**
     * Creates a new ContentLengthHeader based on the newly supplied contentLength value.
     *
     * @param contentLength the new integer value of the contentLength.
     * @throws InvalidArgumentException if supplied contentLength is less
     * than zero.
     * @return the newly created ContentLengthHeader object.
     */
    public ContentLengthHeader createContentLengthHeader(int contentLength) throws InvalidArgumentException {
        final ContentLengthHeader header = new ContentLengthHeaderImpl();
        header.setContentLength(contentLength);
        return header;
    }

    /**
     * Creates a new ContentTypeHeader based on the newly supplied contentType and
     * contentSubType values.
     *
     * @param contentType the new string content type value.
     * @param contentSubType the new string content sub-type value.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the content type or content subtype value.
     * @return the newly created ContentTypeHeader object.
     */
    public ContentTypeHeader createContentTypeHeader(String contentType, String contentSubType) throws ParseException {
        final ContentTypeHeader header = new ContentTypeHeaderImpl();
        header.setContentType(contentType);
        header.setContentSubType(contentSubType);
        return header;
    }

    /**
    * Creates a new DateHeader based on the newly supplied date value.
    *
    * @param date the new Calender value of the date.
    * @return the newly created DateHeader object.
    */
    public DateHeader createDateHeader(Calendar date) {
        final DateHeader header = new DateHeaderImpl();
        header.setDate(date);
        return header;
    }

    /**
     * Creates a new ErrorInfoHeader based on the newly supplied errorInfo value.
     *
     * @param errorInfo the new URI value of the errorInfo.
     * @return the newly created ErrorInfoHeader object.
     */
    public ErrorInfoHeader createErrorInfoHeader(URI errorInfo) {
        final ErrorInfoHeader header = new ErrorInfoHeaderImpl();
        header.setErrorInfo(errorInfo);
        return header;
    }

    /**
     * Creates a new EventHeader based on the newly supplied eventType value.
     *
     * @param eventType the new string value of the eventType.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the eventType value.
     * @return the newly created EventHeader object.
     */
    public EventHeader createEventHeader(String eventType) throws ParseException {
        final EventHeader header = new EventHeaderImpl();
        header.setEventType(eventType);
        return header;
    }

    /**
     * Creates a new ExpiresHeader based on the newly supplied expires value.
     *
     * @param expires the new integer value of the expires.
     * @throws InvalidArgumentException if supplied expires is less
     * than zero.
     * @return the newly created ExpiresHeader object.
     */
    public ExpiresHeader createExpiresHeader(int expires) throws InvalidArgumentException {
        final ExpiresHeader header=new ExpiresHeaderImpl();
        header.setExpires(expires);
        return header;
    }

    /**
     * Creates a new Header based on the newly supplied name and value values.
     * This method can be used to create ExtensionHeaders.
     *
     * @param name the new string name of the Header value.
     * @param value the new string value of the Header.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the name or value values.
     * @return the newly created Header object.
     * @see ExtensionHeader
     */
    public Header createHeader(String name, String value) throws ParseException {
        return new ExtensionHeaderImpl(name, value);
    }

    /**
     * Creates a new List of Headers based on a supplied comma seperated
     * list of Header values for a single header name.
     * This method can be used only for SIP headers whose grammar is of the form
     * header = header-name HCOLON header-value *(COMMA header-value) that
     * allows for combining header fields of the same name into a
     * comma-separated list.  Note that the Contact header field allows a
     * comma-separated list  unless the header field
     * value is "*"
     * @param headers the new string comma seperated list of Header values.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the headers value or a List of that Header
     * type is not allowed.
     * @return the newly created List of Header objects.
     */
    public List createHeaders(String headers) throws ParseException {
        final int colonIndex = headers.indexOf(':');
        if (colonIndex==-1) throw new ParseException("There is no header name!",0);
        final String name = headers.substring(0, colonIndex).trim();
        List<Header> headerList = new ArrayList<Header>();
        StringTokenizer tokener = new StringTokenizer(headers.substring(colonIndex+1).trim(), ",", false);
        while(tokener.hasMoreTokens())
            headerList.add(new ExtensionHeaderImpl(name, tokener.nextToken()));
        return headerList;
    }

    /**
     * Creates a new FromHeader based on the newly supplied address and
     * tag values.
     *
     * @param address the new Address object of the address.
     * @param tag the new string value of the tag.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the tag value.
     * @return the newly created FromHeader object.
     */
    public FromHeader createFromHeader(Address address, String tag) throws ParseException {
        final FromHeader header = new FromHeaderImpl();
        header.setAddress(address);
        header.setTag(tag);
        return header;
    }

    /**
     * Creates a new InReplyToHeader based on the newly supplied callId
     * value.
     *
     * @param callId the new string containing the callId value.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the callId value.
     * @return the newly created InReplyToHeader object.
     */
    public InReplyToHeader createInReplyToHeader(String callId) throws ParseException {
        final InReplyToHeader header = new InReplyToHeaderImpl();
        header.setCallId(callId);
        return header;
    }

    /**
    * Creates a new MaxForwardsHeader based on the newly supplied maxForwards value.
    *
    * @param maxForwards the new integer value of the maxForwards.
    * @throws InvalidArgumentException if supplied maxForwards is less
    * than zero or greater than 255.
    * @return the newly created MaxForwardsHeader object.
    */
    public MaxForwardsHeader createMaxForwardsHeader(int maxForwards) throws InvalidArgumentException {
        final MaxForwardsHeader header = new MaxForwardsHeaderImpl();
        header.setMaxForwards(maxForwards);
        return header;
    }

    /**
     * Creates a new MimeVersionHeader based on the newly supplied mimeVersion
     * values.
     *
     * @param majorVersion the new integer value of the majorVersion.
     * @param minorVersion the new integer value of the minorVersion.
     * @throws InvalidArgumentException if supplied majorVersion or minorVersion
     * is less than zero.
     * @return the newly created MimeVersionHeader object.
     */
    public MimeVersionHeader createMimeVersionHeader(int majorVersion, int minorVersion) throws InvalidArgumentException {
        final MimeVersionHeader header = new MimeVersionHeaderImpl();
        header.setMajorVersion(majorVersion);
        header.setMinorVersion(minorVersion);
        return header;
    }

    /**
     * Creates a new MinExpiresHeader based on the newly supplied minExpires value.
     *
     * @param minExpires the new integer value of the minExpires.
     * @throws InvalidArgumentException if supplied minExpires is less
     * than zero.
     * @return the newly created MinExpiresHeader object.
     */
    public MinExpiresHeader createMinExpiresHeader(int minExpires) throws InvalidArgumentException {
        final MinExpiresHeader header = new MinExpiresHeaderImpl();
        header.setExpires(minExpires);
        return header;
    }

    /**
     * Creates a new OrganizationHeader based on the newly supplied
     * organization value.
     *
     * @param organization the new string value of the organization.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the organization value.
     * @return the newly created OrganizationHeader object.
     */
    public OrganizationHeader createOrganizationHeader(String organization) throws ParseException {
        final OrganizationHeader header = new OrganizationHeaderImpl();
        header.setOrganization(organization);
        return header;
    }

    /**
     * Creates a new PriorityHeader based on the newly supplied priority value.
     *
     * @param priority the new string value of the priority.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the priority value.
     * @return the newly created PriorityHeader object.
     */
    public PriorityHeader createPriorityHeader(String priority) throws ParseException {
        final PriorityHeader header = new PriorityHeaderImpl();
        header.setPriority(priority);
        return header;
    }

    /**
     * Creates a new ProxyAuthenticateHeader based on the newly supplied
     * scheme value.
     *
     * @param scheme the new string value of the scheme.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the scheme value.
     * @return the newly created ProxyAuthenticateHeader object.
     */
    public ProxyAuthenticateHeader createProxyAuthenticateHeader(String scheme) throws ParseException {
        final ProxyAuthenticateHeader header = new ProxyAuthenticateHeaderImpl();
        header.setScheme(scheme);
        return header;
    }

    /**
     * Creates a new ProxyAuthorizationHeader based on the newly supplied
     * scheme value.
     *
     * @param scheme the new string value of the scheme.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the scheme value.
     * @return the newly created ProxyAuthorizationHeader object.
     */
    public ProxyAuthorizationHeader createProxyAuthorizationHeader(String scheme) throws ParseException {
        final ProxyAuthorizationHeader header = new ProxyAuthorizationHeaderImpl();
        header.setScheme(scheme);
        return header;
    }

    /**
     * Creates a new ProxyRequireHeader based on the newly supplied optionTag
     * value.
     *
     * @param optionTag the new string OptionTag value.
     * @return the newly created ProxyRequireHeader object.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the optionTag value.
     */
    public ProxyRequireHeader createProxyRequireHeader(String optionTag) throws ParseException {
        final ProxyRequireHeader header = new ProxyRequireHeaderImpl();
        header.setOptionTag(optionTag);
        return header;
    }

    /**
     * Creates a new RAckHeader based on the newly supplied rSeqNumber,
     * cSeqNumber and method values.
     *
     * @param rSeqNumber the new integer value of the rSeqNumber.
     * @param cSeqNumber the new integer value of the cSeqNumber.
     * @param method the new string value of the method.
     * @throws InvalidArgumentException if supplied rSeqNumber or cSeqNumber is
     * less than zero or greater than than 2**31-1.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the method value.
     * @return the newly created RAckHeader object.
     */
    public RAckHeader createRAckHeader(int rSeqNumber, int cSeqNumber, String method) throws InvalidArgumentException, ParseException {
        final RAckHeader header = new RAckHeaderImpl();
        header.setRSeqNumber(rSeqNumber);
        header.setCSeqNumber(cSeqNumber);
        header.setMethod(method);
        return header;
    }

    /**
     * Creates a new RSeqHeader based on the newly supplied sequenceNumber value.
     *
     * @param sequenceNumber the new integer value of the sequenceNumber.
     * @throws InvalidArgumentException if supplied sequenceNumber is
     * less than zero or greater than than 2**31-1.
     * @return the newly created RSeqHeader object.
     */
    public RSeqHeader createRSeqHeader(int sequenceNumber) throws InvalidArgumentException {
        final RSeqHeader header  = new RSeqHeaderImpl();
        header.setSequenceNumber(sequenceNumber);
        return header;
    }

    /**
     * Creates a new ReasonHeader based on the newly supplied reason value.
     *
     * @param protocol the new string value of the protocol.
     * @param cause the new integer value of the cause.
     * @param text the new string value of the text.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the protocol or text value.
     * @throws InvalidArgumentException if supplied cause is
     * less than zero.
     * @return the newly created ReasonHeader object.
     */
    public ReasonHeader createReasonHeader(String protocol, int cause, String text) throws InvalidArgumentException, ParseException {
        final ReasonHeader header = new ReasonHeaderImpl();
        header.setProtocol(protocol);
        header.setCause(cause);
        header.setText(text);
        return header;
    }

    /**
    * Creates a new RecordRouteHeader based on the newly supplied address value.
    *
    * @param address the new Address object of the address.
    * @return the newly created RecordRouteHeader object.
    */
    public RecordRouteHeader createRecordRouteHeader(Address address) {
        final RecordRouteHeader header = new RecordRouteHeaderImpl();
        header.setAddress(address);
        return header;
    }

    /**
    * Creates a new ReplyToHeader based on the newly supplied address value.
    *
    * @param address the new Address object of the address.
    * @return the newly created ReplyToHeader object.
    */
    public ReplyToHeader createReplyToHeader(Address address) {
        final ReplyToHeader header = new ReplyToHeaderImpl();
        header.setAddress(address);
        return header;
    }

    /**
    * Creates a new ReferToHeader based on the newly supplied address value.
    *
    * @param address the new Address object of the address.
    * @return the newly created ReferToHeader object.
    */
    public ReferToHeader createReferToHeader(Address address) {
        final ReferToHeader header = new ReferToHeaderImpl();
        header.setAddress(address);
        return header;
    }

    /**
     * Creates a new RequireHeader based on the newly supplied optionTag
     * value.
     *
     * @param optionTag the new string value containing the optionTag value.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the List of optionTag value.
     * @return the newly created RequireHeader object.
     */
    public RequireHeader createRequireHeader(String optionTag) throws ParseException {
        final RequireHeader header = new RequireHeaderImpl();
        header.setOptionTag(optionTag);
        return header;
    }

    /**
     * Creates a new RetryAfterHeader based on the newly supplied retryAfter
     * value.
     *
     * @param retryAfter the new integer value of the retryAfter.
     * @throws InvalidArgumentException if supplied retryAfter is less
     * than zero.
     * @return the newly created RetryAfterHeader object.
     */
    public RetryAfterHeader createRetryAfterHeader(int retryAfter) throws InvalidArgumentException {
        final RetryAfterHeader header = new RetryAfterHeaderImpl();
        header.setRetryAfter(retryAfter);
        return header;
    }

    /**
     * Creates a new RouteHeader based on the newly supplied address value.
     *
     * @param address the new Address object of the address.
     * @return the newly created RouteHeader object.
     */
    public RouteHeader createRouteHeader(Address address) {
        final RouteHeader header = new RouteHeaderImpl();
        header.setAddress(address);
        return header;
    }

    /**
     * Creates a new ServerHeader based on the newly supplied List of product
     * values.
     *
     * @param product the new List of values of the product.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the List of product values.
     * @return the newly created ServerHeader object.
     */
    public ServerHeader createServerHeader(List product) throws ParseException {
        final ServerHeader header = new ServerHeaderImpl();
        header.setProduct(product);
        return header;
    }

    /**
      * Creates a new SubjectHeader based on the newly supplied subject value.
      *
      * @param subject the new string value of the subject.
      * @throws ParseException which signals that an error has been reached
      * unexpectedly while parsing the subject value.
      * @return the newly created SubjectHeader object.
      */
    public SubjectHeader createSubjectHeader(String subject) throws ParseException {
        final SubjectHeader header = new SubjectHeaderImpl();
        header.setSubject(subject);
        return header;
    }

    /**
     * Creates a new SubscriptionStateHeader based on the newly supplied
     * subscriptionState value.
     *
     * @param subscriptionState the new string value of the subscriptionState.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the subscriptionState value.
     * @return the newly created SubscriptionStateHeader object.
     */
    public SubscriptionStateHeader createSubscriptionStateHeader(String subscriptionState) throws ParseException {
        final SubscriptionStateHeader header = new SubscriptionStateHeaderImpl();
        header.setState(subscriptionState);
        return header;
    }

    /**
     * Creates a new SupportedHeader based on the newly supplied optionTag
     * value.
     *
     * @param optionTag the new string containing the optionTag value.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the optionTag value.
     * @return the newly created SupportedHeader object.
     */
    public SupportedHeader createSupportedHeader(String optionTag) throws ParseException {
        final SupportedHeader header = new SupportedHeaderImpl();
        header.setOptionTag(optionTag);
        return header;
    }

    /**
     * Creates a new TimeStampHeader based on the newly supplied timeStamp value.
     *
     * @param timeStamp the new float value of the timeStamp.
     * @throws InvalidArgumentException if supplied timeStamp is less
     * than zero.
     * @return the newly created TimeStampHeader object.
     */
    public TimeStampHeader createTimeStampHeader(float timeStamp) throws InvalidArgumentException {
        final TimeStampHeader header = new TimeStampHeaderImpl();
        header.setTimeStamp(timeStamp);
        return header;
    }

    /**
     * Creates a new ToHeader based on the newly supplied address and
     * tag values.
     *
     * @param address the new Address object of the address.
     * @param tag the new string value of the tag, this value may be null.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the tag value.
     * @return the newly created ToHeader object.
     */
    public ToHeader createToHeader(Address address, String tag) throws ParseException {
        final ToHeader header = new ToHeaderImpl();
        header.setAddress(address);
        header.setTag(tag);
        return header;
    }

    //end of to do

    public UnsupportedHeader createUnsupportedHeader(String string) throws ParseException {
        return null;
    }

    public UserAgentHeader createUserAgentHeader(List list) throws ParseException {
        return null;
    }

    public ViaHeader createViaHeader(String string, int i, String string1, String string2) throws ParseException, InvalidArgumentException {
        return null;
    }

    public WWWAuthenticateHeader createWWWAuthenticateHeader(String string) throws ParseException {
        return null;
    }

    public WarningHeader createWarningHeader(String string, int i, String string1) throws InvalidArgumentException, ParseException {
        return null;
    }

    public SIPETagHeader createSIPETagHeader(String string) throws ParseException {
        return null;
    }

    public SIPIfMatchHeader createSIPIfMatchHeader(String string) throws ParseException {
        return null;
    }
}
/*
 * $Log$
 */